package com.united.ucts.modules.juc.thread;

import java.util.*;

/**
 * JUC并发编程学习笔记样例代码
 * ArrayList集合线程不安全样例
 *
 * @author hudan
 * @version 1.0
 * @filename ThreadUnsafeDemo.java
 * @copyright <a href="www.chancein.com">www.chancein.com</a>
 * @date 2022-10-13
 */
public class ThreadUnsafeDemo {

    public static void main(String[] args) {
//        arrayListUnsafeTest();
//
        System.out.println("==============================================================");
        hashSetUnsafeTest();

//        System.out.println("==============================================================");
//        hashMapUnsafeTest();
    }

    public static void arrayListUnsafeTest() {
        // 创建ArrayList集合
        List<String> datas = new ArrayList<>();
        /*
         * 将for循环的值改大时,就会出现java.util.ConcurrentModificationException当值改小时,不一定会出现
         * 出现java.util.ConcurrentModificationException异常的解决方案：
         * 解决方案一: 使用Vector替换掉ArrayList,具体操作就是将上面代码中的new ArrayList<>()更改成new Vector<>(); 但是此方法因为具体的操作是使用的synchronized来修饰add方法,会存在性能问题,因此不推荐使用
         * 解决方案二: 使用Collections,具体操作就是将上面代码中的new ArrayList<>()更改成Collections.synchronizedList(new ArrayList<>()); 它的实质是使用synchronized来修饰add方法里的代码块,也会存在性能问题,因此也不推荐使用
         * 解决方案三: 使用CopyOnWriteArrayList,具体操作就是将上面代码中的new ArrayList<>()更改成new CopyOnWriteArrayList<>()
         */
        for (int i = 0; i < 20; i++) {
            Thread thread = new Thread(() -> {
                // 向集合中添加内容
                datas.add(UUID.randomUUID().toString().substring(0, 8));

                // 从集合中获取内容
                System.out.println(datas);
            }, "this threa name: " + Thread.currentThread().getName() + "will start!");
            thread.start();
        }
    }

    public static void hashSetUnsafeTest() {
        // 创建HashSet集合
        Set<String> datas = new HashSet<>();
        /*
         * 将for循环的值改大时,就会出现java.util.ConcurrentModificationException当值改小时,不一定会出现
         * 出现java.util.ConcurrentModificationException异常的解决方案：
         * 解决方案: 使用CopyOnWriteArraySet,具体操作就是将上面代码中的new HashSet<>()更改成new CopyOnWriteArraySet<>()
         */
        for (int i = 0; i < 50; i++) {
            Thread thread = new Thread(() -> {
                // 向集合中添加内容
                datas.add(UUID.randomUUID().toString().substring(0, 8));

                // 从集合中获取内容
                System.out.println(datas);
            }, "this threa name: " + Thread.currentThread().getName() + "will start!");
            thread.start();
        }
    }

    public static void hashMapUnsafeTest() {
        // 创建HashSet集合
        Map<String, String> datas = new HashMap<>();
        /*
         * 将for循环的值改大时,就会出现java.util.ConcurrentModificationException当值改小时,不一定会出现
         * 出现java.util.ConcurrentModificationException异常的解决方案：
         * 解决方案: 使用ConcurrentHashMap,具体操作就是将上面代码中的73行new HashMap<>()更改成new ConcurrentHashMap<>()
         */
        for (int i = 0; i < 20; i++) {
            Thread thread = new Thread(() -> {
                // 向集合中添加内容
                datas.put(UUID.randomUUID().toString().substring(0, 8), UUID.randomUUID().toString().substring(0, 8));

                // 从集合中获取内容
                System.out.println(datas);
            }, "this threa name: " + Thread.currentThread().getName() + "will start!");
            thread.start();
        }
    }
}